package cn.iocoder.yudao.module.trade.order.service.calculator;

import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.module.api.promotion.activity.enums.PromotionTypeEnum;
import cn.iocoder.yudao.module.api.trade.order.enums.TradeOrderTypeEnum;
import cn.iocoder.yudao.module.trade.order.bo.TradePriceCalculateReqBO;
import cn.iocoder.yudao.module.trade.order.bo.TradePriceCalculateRespBO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.List;

import static cn.iocoder.yudao.module.trade.order.service.calculator.TradePriceCalculatorHelper.formatPrice;

/**
 * 会员价的 {@link TradePriceCalculator} 实现类
 *
 * @author 山野羡民
 */
@Slf4j
@Component
@Order(TradePriceCalculator.ORDER_VIP)
public class TradeVipPriceCalculator implements TradePriceCalculator {

    @Override
    public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
        result.setVipDiscount(calculateVipDiscount(result.getPrice()));
        // 0. 非优惠活动订单，才计算该优惠
        if (Arrays.asList(TradeOrderTypeEnum.SECKILL.getType(), TradeOrderTypeEnum.BARGAIN.getType(),
                        TradeOrderTypeEnum.COMBINATION.getType(), TradeOrderTypeEnum.POINT.getType())
                .contains(result.getType())) {
            log.debug("[calculate][只有非优惠活动订单({})，才处理会员价]", result.getType());
            return;
        }
        if (ObjectUtil.equal(result.getType(), TradeOrderTypeEnum.GROUPON.getType())) {
            log.debug("[calculate][是团购套餐订单，会员价另行计算]");
            return;
        }
        // 1.1 是否使用会员价
        if (!param.isUseVipPrice()) {
            log.debug("[calculate][订单未明确使用会员价，会员价不生效]");
            return;
        }
        // 1.2. 校验会员信息
        if (!Boolean.TRUE.equals(result.getValidVip())) {
            log.debug("[calculate][会员({})不是有效状态，会员价不生效]", param.getUserId());
            return;
        }
        List<TradePriceCalculateRespBO.OrderItem> orderItems = result.getItems();
        // 2. 计算每个 SKU 的优惠金额
        boolean flag = false;
        for (TradePriceCalculateRespBO.OrderItem orderItem : orderItems) {
            // 2.1 是否有会员价
            if (orderItem.getSkuVipPrice() <= 0) {
                log.debug("[calculate][SKU({}) 没有会员价，不处理会员价]", orderItem.getSkuId());
                continue;
            }
            flag = true;
            Integer vipPrice = orderItem.getSkuPrice() - orderItem.getSkuVipPrice();
            // 2.3 更新 SKU 的优惠金额
            orderItem.setVipPrice(vipPrice * orderItem.getCount());
            TradePriceCalculatorHelper.recountPayPrice(orderItem);
        }
        if (flag) {
            List<Integer> vipPrices = orderItems.stream().map(TradePriceCalculateRespBO.OrderItem::getVipPrice).toList();
            TradePriceCalculatorHelper.addPromotion(result, orderItems,
                    param.getUserId(), "会员价", PromotionTypeEnum.VIP.getValue(),
                    String.format("会员价：省 %s 元", formatPrice(vipPrices.stream().reduce(Integer::sum).orElse(0))),
                    vipPrices);
            TradePriceCalculatorHelper.recountAllPrice(result);
        }
        log.debug("[calculate][会员价({})计算完成] {}", flag, result.getPrice());
    }

    private double calculateVipDiscount(TradePriceCalculateRespBO.Price price) {
        BigDecimal totalPrice = new BigDecimal(price.getTotalPrice());
        BigDecimal totalVipPrice = new BigDecimal(price.getTotalVipPrice());
        BigDecimal discount = totalVipPrice.divide(totalPrice, 4, RoundingMode.HALF_UP);
        return discount.multiply(BigDecimal.TEN).setScale(2, RoundingMode.HALF_UP).doubleValue();
    }

}
